Hệ thống quản lý phương tiện trong PHP

1 import { initializer } from './initializer.js';
2 import { htmlParser }
from './html-parser.js';
3
4 /**
5  * Welcome to Typed.js!
6  * @param {
string} elementId HTML element ID _OR_ HTML element
7  * @param {
object} options options object
8  * @returns {
object} a new Typed object
9  */

10 export
default class Typed {
11   constructor(elementId, options) {
12     
// Initialize it up
13     initializer.load(
this, options, elementId);
14     
// All systems go!
15     
this.begin();
16   }
17
18   
/**
19    * Toggle start() and stop() of the Typed instance
20    * @
public
21    */

22   toggle() {
23     
this.pause.status ? this.start() : this.stop();
24   }
25
26   
/**
27    * Stop typing / backspacing and enable cursor blinking
28    * @
public
29    */

30   stop() {
31     
if (this.typingComplete) return;
32     
if (this.pause.status) return;
33     
this.toggleBlinking(true);
34     
this.pause.status = true;
35     
this.options.onStop(this.arrayPos, this);
36   }
37
38   
/**
39    * Start typing / backspacing after being stopped
40    * @
public
41    */

42   start() {
43     
if (this.typingComplete) return;
44     
if (!this.pause.status) return;
45     
this.pause.status = false;
46     
if (this.pause.typewrite) {
47       
this.typewrite(this.pause.curString, this.pause.curStrPos);
48     }
else {
49       
this.backspace(this.pause.curString, this.pause.curStrPos);
50     }
51     
this.options.onStart(this.arrayPos, this);
52   }
53
54   
/**
55    * Destroy
this instance of Typed
56    * @
public
57    */

58   destroy() {
59     
this.reset(false);
60     
this.options.onDestroy(this);
61   }
62
63   
/**
64    * Reset Typed and optionally restarts
65    * @param {boolean} restart
66    * @
public
67    */

68   reset(restart =
true) {
69     clearInterval(
this.timeout);
70     
this.replaceText('');
71     
if (this.cursor && this.cursor.parentNode) {
72       
this.cursor.parentNode.removeChild(this.cursor);
73       
this.cursor = null;
74     }
75     
this.strPos = 0;
76     
this.arrayPos = 0;
77     
this.curLoop = 0;
78     
if (restart) {
79       
this.insertCursor();
80       
this.options.onReset(this);
81       
this.begin();
82     }
83   }
84
85   
/**
86    * Begins the typing animation
87    * @
private
88    */

89   begin() {
90     
this.typingComplete = false;
91     
this.shuffleStringsIfNeeded(this);
92     
this.insertCursor();
93     
if (this.bindInputFocusEvents) this.bindFocusEvents();
94     
this.timeout = setTimeout(() => {
95       
// Check if there is some text in the element, if yes start by backspacing the default message
96       
if (!this.currentElContent || this.currentElContent.length === 0) {
97         
this.typewrite(this.strings[this.sequence[this.arrayPos]], this.strPos);
98       }
else {
99         
// Start typing
100         
this.backspace(this.currentElContent, this.currentElContent.length);
101       }
102     },
this.startDelay);
103   }
104
105   
/**
106    * Called
for each character typed
107    * @param {
string} curString the current string in the strings array
108    * @param {number} curStrPos the current position
in the curString
109    * @
private
110    */

111   typewrite(curString, curStrPos) {
112     
if (this.fadeOut && this.el.classList.contains(this.fadeOutClass)) {
113       
this.el.classList.remove(this.fadeOutClass);
114       
if (this.cursor) this.cursor.classList.remove(this.fadeOutClass);
115     }
116
117     
const humanize = this.humanizer(this.typeSpeed);
118     
let numChars = 1;
119
120     
if (this.pause.status === true) {
121       
this.setPauseStatus(curString, curStrPos, true);
122       
return;
123     }
124
125     
// contain typing function in a timeout humanize'd delay
126     
this.timeout = setTimeout(() => {
127       
// skip over any HTML chars
128       curStrPos = htmlParser.typeHtmlChars(curString, curStrPos,
this);
129
130       
let pauseTime = 0;
131       
let substr = curString.substr(curStrPos);
132       
// check for an escape character before a pause value
133       
// format: \^\d+ .. eg: ^1000 .. should be able to print the ^ too using ^^
134       
// single ^ are removed from string
135       
if (substr.charAt(0) === '^') {
136         
if (/^\^\d+/.test(substr)) {
137           
let skip = 1; // skip at least 1
138           substr = /\d+/.exec(substr)[
0];
139           skip += substr.length;
140           pauseTime = parseInt(substr);
141           
this.temporaryPause = true;
142           
this.options.onTypingPaused(this.arrayPos, this);
143           
// strip out the escape character and pause value so they're not printed
144           curString = curString.substring(
0, curStrPos) + curString.substring(curStrPos + skip);
145           
this.toggleBlinking(true);
146         }
147       }
148
149       
// check for skip characters formatted as
150       
// "this is a `string to print NOW` ..."
151       
if (substr.charAt(0) === '`') {
152         
while (curString.substr(curStrPos + numChars).charAt(0) !== '`') {
153           numChars++;
154           
if (curStrPos + numChars > curString.length) break;
155         }
156         
// strip out the escape characters and append all the string in between
157         
const stringBeforeSkip = curString.substring(0, curStrPos);
158         
const stringSkipped = curString.substring(stringBeforeSkip.length + 1, curStrPos + numChars);
159         
const stringAfterSkip = curString.substring(curStrPos + numChars + 1);
160         curString = stringBeforeSkip + stringSkipped + stringAfterSkip;
161         numChars--;
162       }
163
164       
// timeout for any pause after a character
165       
this.timeout = setTimeout(() => {
166         
// Accounts for blinking while paused
167         
this.toggleBlinking(false);
168
169         
// We're done with this sentence!
170         
if (curStrPos === curString.length) {
171           
this.doneTyping(curString, curStrPos);
172         }
else {
173           
this.keepTyping(curString, curStrPos, numChars);
174         }
175         
// end of character pause
176         
if (this.temporaryPause) {
177           
this.temporaryPause = false;
178           
this.options.onTypingResumed(this.arrayPos, this);
179         }
180       }, pauseTime);
181
182       
// humanized value for typing
183     }, humanize);
184   }
185
186   
/**
187    * Continue to the next
string & begin typing
188    * @param {
string} curString the current string in the strings array
189    * @param {number} curStrPos the current position
in the curString
190    * @
private
191    */

192   keepTyping(curString, curStrPos, numChars) {
193     
// call before functions if applicable
194     
if (curStrPos === 0) {
195       
this.toggleBlinking(false);
196       
this.options.preStringTyped(this.arrayPos, this);
197     }
198     
// start typing each new char into existing string
199     
// curString: arg, this.el.html: original text inside element
200     curStrPos += numChars;
201     
const nextString = curString.substr(0, curStrPos);
202     
this.replaceText(nextString);
203     
// loop the function
204     
this.typewrite(curString, curStrPos);
205   }
206
207   
/**
208    * We
're done typing all strings
209    * @param {
string} curString the current string in the strings array
210    * @param {number} curStrPos the current position
in the curString
211    * @
private
212    */

213   doneTyping(curString, curStrPos) {
214     
// fires callback function
215     
this.options.onStringTyped(this.arrayPos, this);
216     
this.toggleBlinking(true);
217     
// is this the final string
218     
if (this.arrayPos === this.strings.length - 1) {
219       
// callback that occurs on the last typed string
220       
this.complete();
221       
// quit if we wont loop back
222       
if (this.loop === false || this.curLoop === this.loopCount) {
223         
return;
224       }
225     }
226     
this.timeout = setTimeout(() => {
227       
this.backspace(curString, curStrPos);
228     },
this.backDelay);
229   }
230
231   
/**
232    * Backspaces
1 character at a time
233    * @param {
string} curString the current string in the strings array
234    * @param {number} curStrPos the current position
in the curString
235    * @
private
236    */

237   backspace(curString, curStrPos) {
238     
if (this.pause.status === true) {
239       
this.setPauseStatus(curString, curStrPos, true);
240       
return;
241     }
242     
if (this.fadeOut) return this.initFadeOut();
243
244     
this.toggleBlinking(false);
245     
const humanize = this.humanizer(this.backSpeed);
246
247     
this.timeout = setTimeout(() => {
248       curStrPos = htmlParser.backSpaceHtmlChars(curString, curStrPos,
this);
249       
// replace text with base text + typed characters
250       
const curStringAtPosition = curString.substr(0, curStrPos);
251       
this.replaceText(curStringAtPosition);
252
253       
// if smartBack is enabled
254       
if (this.smartBackspace) {
255         
// the remaining part of the current string is equal of the same part of the new string
256         
let nextString = this.strings[this.arrayPos + 1];
257         
if (nextString && curStringAtPosition === nextString.substr(0, curStrPos)) {
258           
this.stopNum = curStrPos;
259         }
else {
260           
this.stopNum = 0;
261         }
262       }
263
264       
// if the number (id of character in current string) is
265       
// less than the stop number, keep going
266       
if (curStrPos > this.stopNum) {
267         
// subtract characters one by one
268         curStrPos--;
269         
// loop the function
270         
this.backspace(curString, curStrPos);
271       }
else if (curStrPos <= this.stopNum) {
272         
// if the stop number has been reached, increase
273         
// array position to next string
274         
this.arrayPos++;
275         
// When looping, begin at the beginning after backspace complete
276         
if (this.arrayPos === this.strings.length) {
277           
this.arrayPos = 0;
278           
this.options.onLastStringBackspaced();
279           
this.shuffleStringsIfNeeded();
280           
this.begin();
281         }
else {
282           
this.typewrite(this.strings[this.sequence[this.arrayPos]], curStrPos);
283         }
284       }
285       
// humanized value for typing
286     }, humanize);
287   }
288
289   
/**
290    * Full animation
is complete
291    * @
private
292    */

293   complete() {
294     
this.options.onComplete(this);
295     
if (this.loop) {
296       
this.curLoop++;
297     }
else {
298       
this.typingComplete = true;
299     }
300   }
301
302   
/**
303    * Has the typing been stopped
304    * @param {
string} curString the current string in the strings array
305    * @param {number} curStrPos the current position
in the curString
306    * @param {boolean} isTyping
307    * @
private
308    */

309   setPauseStatus(curString, curStrPos, isTyping) {
310     
this.pause.typewrite = isTyping;
311     
this.pause.curString = curString;
312     
this.pause.curStrPos = curStrPos;
313   }
314
315   
/**
316    * Toggle the blinking cursor
317    * @param {boolean} isBlinking
318    * @
private
319    */

320   toggleBlinking(isBlinking) {
321     
if (!this.cursor) return;
322     
// if in paused state, don't toggle blinking a 2nd time
323     
if (this.pause.status) return;
324     
if (this.cursorBlinking === isBlinking) return;
325     
this.cursorBlinking = isBlinking;
326     
const status = isBlinking ? 'infinite' : 0;
327     
this.cursor.style.animationIterationCount = status;
328   }
329
330   
/**
331    * Speed
in MS to type
332    * @param {number} speed
333    * @
private
334    */

335   humanizer(speed) {
336     
return Math.round(Math.random() * speed / 2) + speed;
337   }
338
339   
/**
340    * Shuffle the sequence of the strings array
341    * @
private
342    */

343   shuffleStringsIfNeeded() {
344     
if (!this.shuffle) return;
345     
this.sequence = this.sequence.sort(() => Math.random() - 0.5);
346   }
347
348   
/**
349    * Adds a CSS
class to fade out current string
350    * @
private
351    */

352   initFadeOut() {
353     
this.el.className += ` ${this.fadeOutClass}`;
354     
if (this.cursor) this.cursor.className += ` ${this.fadeOutClass}`;
355     
return setTimeout(() => {
356       
this.arrayPos++;
357       
this.replaceText('');
358
359       
// Resets current string if end of loop reached
360       
if (this.strings.length > this.arrayPos) {
361         
this.typewrite(this.strings[this.sequence[this.arrayPos]], 0);
362       }
else {
363         
this.typewrite(this.strings[0], 0);
364         
this.arrayPos = 0;
365       }
366     },
this.fadeOutDelay);
367   }
368
369   
/**
370    * Replaces current text
in the HTML element
371    * depending
on element type
372    * @param {
string} str
373    * @
private
374    */

375   replaceText(str) {
376     
if (this.attr) {
377       
this.el.setAttribute(this.attr, str);
378     }
else {
379       
if (this.isInput) {
380         
this.el.value = str;
381       }
else if (this.contentType === 'html') {
382         
this.el.innerHTML = str;
383       }
else {
384         
this.el.textContent = str;
385       }
386     }
387   }
388
389   
/**
390    * If
using input elements, bind focus in order to
391    * start and stop the animation
392    * @
private
393    */

394   bindFocusEvents() {
395     
if (!this.isInput) return;
396     
this.el.addEventListener('focus', (e) => {
397       
this.stop();
398     });
399     
this.el.addEventListener('blur', (e) => {
400       
if (this.el.value && this.el.value.length !== 0) { return; }
401       
this.start();
402     });
403   }
404
405   
/**
406    * On init, insert the cursor element
407    * @
private
408    */

409   insertCursor() {
410     
if (!this.showCursor) return;
411     
if (this.cursor) return;
412     
this.cursor = document.createElement('span');
413     
this.cursor.className = 'typed-cursor';
414     
this.cursor.innerHTML = this.cursorChar;
415     
this.el.parentNode && this.el.parentNode.insertBefore(this.cursor, this.el.nextSibling);
416   }
417 }


Gõ tìm kiếm nhanh...